package htmlReader;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.log4j.Logger;

import aut.commons.threadPool.ThreadPool;

public class ReadBatchHtml {	
	
	private static Logger log = Logger.getLogger("downtv");
	
	private static final String TVHOST = "epg.tvsou.com";
	
	private static Map errorHtmlMap = new HashMap();
	
	private String channelDirNm = null;
	
	public ReadBatchHtml(String channelDirNm){
		this.channelDirNm = channelDirNm;
	}
	
	protected void batchReadHtml(Map htmlMap) throws IOException{
		if(htmlMap == null || htmlMap.size() == 0){
			log.info("html processed is none!");
			log.info("html processed is none!");
			return;
		}
		
		InetAddress address = InetAddress.getByName(TVHOST);
		SocketAddress socketAddress = new InetSocketAddress(address, 80);
		
		log.info("Start batch read html time: " + new Date());
		log.info("Start batch read html time: " + new Date());
		batchRead(htmlMap, socketAddress);
		log.info(errorHtmlMap);
		log.info("errorHtml: " + errorHtmlMap);
		
		while(errorHtmlMap.size() != 0){
			Map temp = new HashMap(errorHtmlMap);
			errorHtmlMap.clear();
			batchRead(temp, socketAddress);			
		}		
		log.info("End batch read html time: " + new Date());
		log.info("End batch read html time: " + new Date());
	}
	
	private final void batchRead(Map map, SocketAddress socketAddress) throws IOException{

		log.info("Start one time batch read html: " + new Date());
		log.info("Start one time batch read html: " + new Date());
		List workers = new ArrayList();
		Iterator it = map.entrySet().iterator();
		while(it.hasNext()){
			Entry entry = (Entry)it.next();				
			String tvPath =  entry.getKey().toString();
			String saveFNPre = entry.getValue().toString();
			ReadHtml readHtml = new ReadHtml(channelDirNm, TVHOST, socketAddress);
			workers.add(new Worker(readHtml, tvPath, saveFNPre));
		}
		
		ThreadPool threadPool = new ThreadPool(20);
		for(int i = 0; i < workers.size(); i++){
			threadPool.execute((Worker)workers.get(i));
		}
		for(int i = 0; i < workers.size(); i++){
			Worker item = (Worker)workers.get(i);
			synchronized(item){
				while(!item.isOver()){
					try {
						item.wait();
					} catch (InterruptedException e) {
						log.error(e, e);
						e.printStackTrace();
					}
				}
			}
		}
		threadPool.overPool();
		log.info("End one time batch read html: " + new Date());
		log.info("End one time batch read html: " + new Date());
	}	
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {	
		try {
			PrepareReading prepareReading = new PrepareReading();
			prepareReading.makePreparations();
			ReadBatchHtml readBatchHtml = new ReadBatchHtml(prepareReading.getChannelDirNm());
			readBatchHtml.batchReadHtml(prepareReading.getHtmlMap());
		} catch (Exception e) {
			log.error(e, e);
			e.printStackTrace();
		}
	}
	
	private final void addErrorHtml(String tvPath, String saveFNPre){		
		errorHtmlMap.put(tvPath, saveFNPre);
	}
	
	class Worker implements Runnable{
		
		private boolean overFlag = false;
		private ReadHtml readHtml = null;
		private String tvPath = null;
		private String saveFNPre = null;		
		
		public Worker(ReadHtml readHtml, String tvPath, String saveFNPre) {
			this.readHtml = readHtml;
			this.tvPath = tvPath;
			this.saveFNPre = saveFNPre;			
		}

		public void run() {	
			/*for(int i = 1; i <= 7; i++){
				StringBuffer tvPathTmp = new StringBuffer(tvPath + "W" + i + ".htm");
				StringBuffer saveFNPreTmp = new StringBuffer(saveFNPre + "_" + week[i - 1] + ".html");
				readHtml.readBinHtml(tvPathTmp.toString(), saveFNPreTmp.toString());
			}*/
			try {
				readHtml.readBinHtml(tvPath, saveFNPre);
			} catch (Exception e) {
				addErrorHtml(tvPath, saveFNPre);
				log.error("read html error: " + channelDirNm + saveFNPre, e);
				e.printStackTrace();
			}			
			synchronized(this){
				overFlag = true;
				this.notify();
			}
		}
		
		public boolean isOver(){
			return overFlag;
		}
	}
}
